﻿using NUnit.Framework;
using Inovout.Descriptors;
using Inovout.Models;

namespace Inovout.Service.Tests.Model
{
    [TestFixture]
    public class DataObjectPropertyTestCase
    {
        private IntIdDataObject testIdValueDataObject_0_Null;
        private IntIdDataObject testIdValueDataObject_0_Empty;
        private IntIdDataObject testIdValueDataObject_0_a;
        private IntIdDataObject testIdValueDataObject_1_Null;
        private IntIdDataObject testIdValueDataObject_1_Empty;
        private IntIdDataObject testIdValueDataObject_1_a;
        private IntIdDataObject targetIdValueDataObject_0_Null;
        private IntIdDataObject targetIdValueDataObject_0_Empty;
        private IntIdDataObject targetIdValueDataObject_0_a;
        private IntIdDataObject targetIdValueDataObject_0_b;
        private IntIdDataObject targetIdValueDataObject_1_Null;
        private IntIdDataObject targetIdValueDataObject_1_Empty;
        private IntIdDataObject targetIdValueDataObject_1_a;
        private IntIdDataObject targetIdValueDataObject_1_b;
        private IntIdDataObject targetIdValueDataObject_2_Null;
        private IntIdDataObject targetIdValueDataObject_2_Empty;
        private IntIdDataObject targetIdValueDataObject_2_a;
        private IntIdDataObject targetIdValueDataObject_2_b;

        [SetUp]
        public void TestInitialize()
        {
            TypeDescriptor typeDescriptor = new TypeDescriptor(typeof(IntIdDataObject));
            FieldDescriptor idFieldDescriptor = typeDescriptor.GetField("id");
            FieldDescriptor nameFieldDescriptor = typeDescriptor.GetField("name");

            testIdValueDataObject_0_Null = new IntIdDataObject();
            testIdValueDataObject_0_Empty = new IntIdDataObject();
            nameFieldDescriptor.SetValue(testIdValueDataObject_0_Empty, string.Empty);
            testIdValueDataObject_0_a = new IntIdDataObject();
            nameFieldDescriptor.SetValue(testIdValueDataObject_0_a, "a");

            testIdValueDataObject_1_Null = new IntIdDataObject();
            idFieldDescriptor.SetValue(testIdValueDataObject_1_Null, 1);
            testIdValueDataObject_1_Empty = new IntIdDataObject();
            idFieldDescriptor.SetValue(testIdValueDataObject_1_Empty, 1);
            nameFieldDescriptor.SetValue(testIdValueDataObject_1_Empty, string.Empty);
            testIdValueDataObject_1_a = new IntIdDataObject();
            idFieldDescriptor.SetValue(testIdValueDataObject_1_a, 1);
            nameFieldDescriptor.SetValue(testIdValueDataObject_1_a, "a");

            targetIdValueDataObject_0_Null = new IntIdDataObject();
            targetIdValueDataObject_0_Empty = new IntIdDataObject();
            nameFieldDescriptor.SetValue(targetIdValueDataObject_0_Empty, string.Empty);
            targetIdValueDataObject_0_a = new IntIdDataObject();
            nameFieldDescriptor.SetValue(targetIdValueDataObject_0_a, "a");
            targetIdValueDataObject_0_b = new IntIdDataObject();
            nameFieldDescriptor.SetValue(targetIdValueDataObject_0_b, "b");


            targetIdValueDataObject_1_Null = new IntIdDataObject();
            idFieldDescriptor.SetValue(targetIdValueDataObject_1_Null, 1);
            targetIdValueDataObject_1_Empty = new IntIdDataObject();
            idFieldDescriptor.SetValue(targetIdValueDataObject_1_Empty, 1);
            nameFieldDescriptor.SetValue(targetIdValueDataObject_1_Empty, string.Empty);
            targetIdValueDataObject_1_a = new IntIdDataObject();
            nameFieldDescriptor.SetValue(targetIdValueDataObject_1_a, "a");
            targetIdValueDataObject_1_b = new IntIdDataObject();
            idFieldDescriptor.SetValue(targetIdValueDataObject_1_b, 1);
            nameFieldDescriptor.SetValue(targetIdValueDataObject_1_b, "b");

            targetIdValueDataObject_2_Null = new IntIdDataObject();
            idFieldDescriptor.SetValue(targetIdValueDataObject_2_Null, 2);
            targetIdValueDataObject_2_Empty = new IntIdDataObject();
            idFieldDescriptor.SetValue(targetIdValueDataObject_2_Empty, 2);
            nameFieldDescriptor.SetValue(targetIdValueDataObject_2_Empty, string.Empty);
            targetIdValueDataObject_2_a = new IntIdDataObject();
            nameFieldDescriptor.SetValue(targetIdValueDataObject_2_a, "a");
            targetIdValueDataObject_2_b = new IntIdDataObject();
            idFieldDescriptor.SetValue(targetIdValueDataObject_2_b, 2);
            nameFieldDescriptor.SetValue(targetIdValueDataObject_2_b, "b");
        }

        [Test]
        public void EqualsTest()
        {
            bool expected;
            bool actual;

            expected = false;
            actual = testIdValueDataObject_0_Null.Equals(null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Null.Equals(null)");


            #region Source-0,Null
            //0,Null
            expected = false;
            actual = testIdValueDataObject_0_Null.Equals(targetIdValueDataObject_0_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Null.Equals(targetIdValueDataObject_0_Null)");

            //0,Empty
            expected = false;
            actual = testIdValueDataObject_0_Null.Equals(targetIdValueDataObject_0_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Null.Equals(targetIdValueDataObject_0_Empty)");

            //0,a
            expected = false;
            actual = testIdValueDataObject_0_Null.Equals(targetIdValueDataObject_0_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Null.Equals(targetIdValueDataObject_0_a)");

            //1,Null
            expected = false;
            actual = testIdValueDataObject_0_Null.Equals(targetIdValueDataObject_1_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Null.Equals(targetIdValueDataObject_1_Null)");

            //1,Empty
            expected = false;
            actual = testIdValueDataObject_0_Null.Equals(targetIdValueDataObject_1_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Null.Equals(targetIdValueDataObject_1_Empty)");

            //1,a
            expected = false;
            actual = testIdValueDataObject_0_Null.Equals(targetIdValueDataObject_1_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Null.Equals(targetIdValueDataObject_1_a)");
            #endregion

            #region Source-0,Empty

            //0,Null
            expected = false;
            actual = testIdValueDataObject_0_Empty.Equals(targetIdValueDataObject_0_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Empty.Equals(targetIdValueDataObject_0_Null)");

            //0,Empty
            expected = false;
            actual = testIdValueDataObject_0_Empty.Equals(targetIdValueDataObject_0_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Empty.Equals(targetIdValueDataObject_0_Empty)");

            //0,a
            expected = false;
            actual = testIdValueDataObject_0_Empty.Equals(targetIdValueDataObject_0_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Empty.Equals(targetIdValueDataObject_0_a)");

            //1,Null
            expected = false;
            actual = testIdValueDataObject_0_Empty.Equals(targetIdValueDataObject_1_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Empty.Equals(targetIdValueDataObject_1_Null)");

            //1,Empty
            expected = false;
            actual = testIdValueDataObject_0_Empty.Equals(targetIdValueDataObject_1_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Empty.Equals(targetIdValueDataObject_1_Empty)");

            //1,a
            expected = false;
            actual = testIdValueDataObject_0_Empty.Equals(targetIdValueDataObject_1_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_Empty.Equals(targetIdValueDataObject_1_a)");
            #endregion

            #region Source-0,a

            //0,Null
            expected = false;
            actual = testIdValueDataObject_0_a.Equals(targetIdValueDataObject_0_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_a.Equals(targetIdValueDataObject_0_Null)");

            //0,Empty
            expected = false;
            actual = testIdValueDataObject_0_a.Equals(targetIdValueDataObject_0_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_a.Equals(targetIdValueDataObject_0_Empty)");

            //0,a
            expected = false;
            actual = testIdValueDataObject_0_a.Equals(targetIdValueDataObject_0_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_a.Equals(targetIdValueDataObject_0_a)");

            //1,Null
            expected = false;
            actual = testIdValueDataObject_0_a.Equals(targetIdValueDataObject_1_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_a.Equals(targetIdValueDataObject_1_Null)");

            //1,Empty
            expected = false;
            actual = testIdValueDataObject_0_a.Equals(targetIdValueDataObject_1_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_a.Equals(targetIdValueDataObject_1_Empty)");

            //1,a
            expected = false;
            actual = testIdValueDataObject_0_a.Equals(targetIdValueDataObject_1_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_a.Equals(targetIdValueDataObject_1_a)");

            //1,b
            expected = false;
            actual = testIdValueDataObject_0_a.Equals(targetIdValueDataObject_1_b);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_0_a.Equals(targetIdValueDataObject_1_b)");


            #endregion


            #region Source-1,Null
            //0,Null
            expected = false;
            actual = testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_0_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_0_Null)");

            //0,Empty
            expected = false;
            actual = testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_0_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_0_Empty)");

            //0,a
            expected = false;
            actual = testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_0_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_0_a)");

            //1,Null
            expected = true;
            actual = testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_1_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_1_Null)");

            //1,Empty
            expected = true;
            actual = testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_1_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_1_Empty)");

            //1,a
            expected = false;
            actual = testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_1_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_1_a)");

            //2,Null
            expected = false;
            actual = testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_2_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_2_Null)");

            //2,Empty
            expected = false;
            actual = testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_2_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_2_Empty)");

            //2,a
            expected = false;
            actual = testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_2_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Null.Equals(targetIdValueDataObject_2_a)");

            #endregion

            #region Source-1,Empty
            //0,Null
            expected = false;
            actual = testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_0_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_0_Null)");

            //0,Empty
            expected = false;
            actual = testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_0_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_0_Empty)");

            //0,a
            expected = false;
            actual = testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_0_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_0_a)");

            //1,Null
            expected = true;
            actual = testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_1_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_1_Null)");

            //1,Empty
            expected = true;
            actual = testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_1_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_1_Empty)");

            //1,a
            expected = false;
            actual = testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_1_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_1_a)");

            //2,Null
            expected = false;
            actual = testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_2_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_2_Null)");

            //2,Empty
            expected = false;
            actual = testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_2_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_2_Empty)");

            //2,a
            expected = false;
            actual = testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_2_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_Empty.Equals(targetIdValueDataObject_2_a)");

            #endregion

            #region Source-1,a

            //0,Null
            expected = false;
            actual = testIdValueDataObject_1_a.Equals(targetIdValueDataObject_0_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_a.Equals(targetIdValueDataObject_0_Null)");

            //0,Empty
            expected = false;
            actual = testIdValueDataObject_1_a.Equals(targetIdValueDataObject_0_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_a.Equals(targetIdValueDataObject_0_Empty)");

            //0,a
            expected = false;
            actual = testIdValueDataObject_1_a.Equals(targetIdValueDataObject_0_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_a.Equals(targetIdValueDataObject_0_a)");

            //1,Null
            expected = false;
            actual = testIdValueDataObject_1_a.Equals(targetIdValueDataObject_1_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_a.Equals(targetIdValueDataObject_1_Null)");

            //1,Empty
            expected = false;
            actual = testIdValueDataObject_1_a.Equals(targetIdValueDataObject_1_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_a.Equals(targetIdValueDataObject_1_Empty)");

            //1,a
            expected = false;
            actual = testIdValueDataObject_1_a.Equals(targetIdValueDataObject_1_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_a.Equals(targetIdValueDataObject_1_a)");

            //1,b
            expected = false;
            actual = testIdValueDataObject_1_a.Equals(targetIdValueDataObject_1_b);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_a.Equals(targetIdValueDataObject_1_b)");


            //2,Null
            expected = false;
            actual = testIdValueDataObject_1_a.Equals(targetIdValueDataObject_2_Null);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_a.Equals(targetIdValueDataObject_2_Null)");

            //2,Empty
            expected = false;
            actual = testIdValueDataObject_1_a.Equals(targetIdValueDataObject_2_Empty);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_a.Equals(targetIdValueDataObject_2_Empty)");

            //2,a
            expected = false;
            actual = testIdValueDataObject_1_a.Equals(targetIdValueDataObject_2_a);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_a.Equals(targetIdValueDataObject_2_a)");

            //2,b
            expected = false;
            actual = testIdValueDataObject_1_a.Equals(targetIdValueDataObject_2_b);
            Assert.AreEqual(expected, actual, "testIdValueDataObject_1_a.Equals(targetIdValueDataObject_2_b)");


            #endregion
        }

        public class IntIdDataObject : DataObject
        {
            private string name;
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
            public override bool Equals(DataObject other)
            {
                if (!base.Equals(other))
                {
                    return false;
                }
                return Comparer.Equals(this.Name, ((IntIdDataObject)other).Name);
            }

            public override int GetHashCode()
            {
                if (string.IsNullOrEmpty(name))
                {
                    return base.GetHashCode();
                }
                else
                {
                    return name.GetHashCode();
                }
            }
        }
    }
}
